package org.glickr.api.photos

import org.glickr.api.FlickrApiMethod
import org.glickr.FlickrPhoto
import org.glickr.enums.FlickrSizeSuffix
import groovy.util.slurpersupport.GPathResult
import org.glickr.FlickrPhotoSize
import org.glickr.FlickrServicePluginException
import org.glickr.FlickrServiceApiException

/* ----------------------------------------------------------------------------------------------------
REQUEST: flickr.photos.getSizes
INFO: Returns the available sizes for a photo.  The calling user must have permission to view the photo.

AUTHENTICATION: This method does not require authentication.

ARGUMENTS:
api_key (Required): Your API application key.
photo_id (Required): The id of the photo to fetch size information for.

EXAMPLE RESPONSE:
<sizes canblog="1" canprint="1" candownload="1">
  <size label="Square" width="75" height="75" source="http://farm2.staticflickr.com/1103/567229075_2cf8456f01_s.jpg" url="http://www.flickr.com/photos/stewart/567229075/sizes/sq/" media="photo" />
  <size label="Large Square" width="150" height="150" source="http://farm2.staticflickr.com/1103/567229075_2cf8456f01_q.jpg" url="http://www.flickr.com/photos/stewart/567229075/sizes/q/" media="photo" />
  <size label="Thumbnail" width="100" height="75" source="http://farm2.staticflickr.com/1103/567229075_2cf8456f01_t.jpg" url="http://www.flickr.com/photos/stewart/567229075/sizes/t/" media="photo" />
  <size label="Small" width="240" height="180" source="http://farm2.staticflickr.com/1103/567229075_2cf8456f01_m.jpg" url="http://www.flickr.com/photos/stewart/567229075/sizes/s/" media="photo" />
  <size label="Small 320" width="320" height="240" source="http://farm2.staticflickr.com/1103/567229075_2cf8456f01_n.jpg" url="http://www.flickr.com/photos/stewart/567229075/sizes/n/" media="photo" />
  <size label="Medium" width="500" height="375" source="http://farm2.staticflickr.com/1103/567229075_2cf8456f01.jpg" url="http://www.flickr.com/photos/stewart/567229075/sizes/m/" media="photo" />
  <size label="Medium 640" width="640" height="480" source="http://farm2.staticflickr.com/1103/567229075_2cf8456f01_z.jpg?zz=1" url="http://www.flickr.com/photos/stewart/567229075/sizes/z/" media="photo" />
  <size label="Medium 800" width="800" height="600" source="http://farm2.staticflickr.com/1103/567229075_2cf8456f01_c.jpg" url="http://www.flickr.com/photos/stewart/567229075/sizes/c/" media="photo" />
  <size label="Large" width="1024" height="768" source="http://farm2.staticflickr.com/1103/567229075_2cf8456f01_b.jpg" url="http://www.flickr.com/photos/stewart/567229075/sizes/l/" media="photo" />
  <size label="Original" width="2400" height="1800" source="http://farm2.staticflickr.com/1103/567229075_6dc09dc6da_o.jpg" url="http://www.flickr.com/photos/stewart/567229075/sizes/o/" media="photo" />
</sizes>
---------------------------------------------------------------------------------------------------- */

class photosGetSizes implements FlickrApiMethod {
    //
    //  API METHOD
    //
    static final String apiMethod = 'flickr.photos.getSizes'

    //
    //  VALIDATOR
    //
    def validatorClosure = { FlickrPhoto photo ->
        if (!photo || !photo?.id) { return [validated:false, message:"Required value 'FlickrPhoto.id' is missing"] }
        return [validated:true]
    }

    //
    //  PARAMS
    //
    def paramsClosure = { FlickrPhoto photo ->
        [photo_id:photo?.id]
    }

    //
    //  PROCESSOR
    //
    def processorClosure = { GPathResult response, FlickrPhoto photo ->

        photo.canBlog     = (response.sizes.@canblog?.toString()     == '1')
        photo.canPrint    = (response.sizes.@canprint?.toString()    == '1')
        photo.canDownload = (response.sizes.@candownload?.toString() == '1')

        photo.sizes = []
        response.sizes.size.each{
            try {
                photo.sizes?.add(
                    new FlickrPhotoSize(
                        suffix:Enum.valueOf( FlickrSizeSuffix, it.@label?.toString()?.replaceAll(/ /,"") ),
                        width: it.@width.toInteger(),
                        height: it.@height.toInteger(),
                        source: it.@source.toString(),
                        url: it.@url.toString(),
                        media: it.@media.toString()
                    )
                )
            } catch (IllegalArgumentException ex) {
                // todo size not found in FlickrSizeSuffix enum
            }
        }
        return photo
    }

    //
    //  ERROR CODES
    //
    Closure errorsClosure = { GPathResult response ->
        if (response.err.@code.toInteger() == 1) { return null }      // photo not found
        if (response.err.@code.toInteger() == 2) { return null }      // permission denied

        // recoverable errors
        if ([100,105,116].contains(response.err.@code.toInteger())) {
            return new FlickrServiceApiException(response)
        } else {
            return new FlickrServicePluginException(response)
        }
    }
}
